#ifndef TB_DB_DB_INTERFACE_HPP__
#define TB_DB_DB_INTERFACE_HPP__

#include "tbcore/base/blob.hpp"
#include "tbcore/base/string.hpp"
#include "tbcore/base/result.hpp"
#include "tbcore/reflection/variant.hpp"

#include "db_fwd.hpp"
#include "db_export.hpp"

TB_NAMESPACE_BEGIN

typedef void* DBFilterInterface;

struct DBiterator {
	virtual Result Next(const char** key, size_t& keylen, 
		const char** val, size_t& vallen) = 0;
};

bool DefaultKeyPred(const Blob& key, const Blob& min, const Blob& max) {
  if (key.size() == min.size() && key.size() == max.size()) {
    return memcmp(key.data(), min.data(), key.size()) >= 0 &&
      memcmp(key.data(), max.data(), key.size()) <= 0;
  }
  return false;
}

struct DBInterface {
	typedef bool(*RangeProcT)(const Blob& key, const Blob& min, const Blob& max);

	virtual ~DBInterface() {};

	//database management
	virtual Result OpenDB(const String& param, 
		bool createIfNotExist = true, bool readOnly = false) = 0;
	virtual Result CloseDB() = 0;
	virtual Result DestroyDB(const String& param) = 0;

	//write operation
	virtual Result Write(const Blob& key, const char* val, uint32 vallen) = 0;
	virtual Result WriteValue(const Blob& key, const Variant& val) = 0;
	virtual Result WriteBatch(const Blob* key, const Variant* vals, uint32 len) = 0;
	virtual void Flush() = 0;

	//read operation
	virtual Result Read(const Blob& key, char** val, uint32& vallen) = 0;
	virtual Result ReadValue(const Blob& key, Variant& val) = 0;
	virtual DBIteratorPtr ReadFilter(DBFilterInterface* filter) = 0;
	virtual Result ReadBatch(const Blob* keys, uint32 keylen,
		char** vallist, size_t& valsizelist) = 0;
  virtual DBIteratorPtr ReadByRange(const Blob& minkey, const Blob& maxkey, 
    const _STD string& prefix = _STD string(), RangeProcT pred = DefaultKeyPred) = 0;

	//delete operation
	virtual Result Delete(const Blob& key) = 0;
	virtual Result DeleteFilter(DBFilterInterface* filter, bool onlyOnce) = 0;
	virtual Result DeleteBatch(const Blob* key, uint32 keylen) = 0;
	virtual Result DeleteByRange(const Blob& minkey, const Blob& maxkey, 
		RangeProcT pred = nullptr) = 0;
};

TB_DB_API DBInterface* CreateRocksDB();

TB_NAMESPACE_END

#endif // TB_DB_DB_INTERFACE_HPP__
